﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace IntegratedOnBordDebug.UDPCore
{
    public class UDPClientServer
    {
        UdpClient Client;

        public delegate void ReceiveData(byte[] args, IPEndPoint ipe);
        public event ReceiveData ReceiveDataEvent;

        public UDPClientServer(IPEndPoint ip)
        {
            try
            {
                Client = new UdpClient();

                //uint IOC_IN = 0x80000000;
                //uint IOC_VENDOR = 0x18000000;
                //uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;

                //Client.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
                Client.Client.ReceiveBufferSize = 1000;
                Client.Client.SendBufferSize = 1000;
                Client.Client.Bind(ip);
                Debug.Write("listen done.");
            }
            catch (Exception ex)
            {
                Console.Write("listen error"+ex.Message);
            }
            
        }


        public void StartReceive()
        {
            try
            {
                Client.BeginReceive(new AsyncCallback(OnReceive), Client);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }


        private void OnReceive(IAsyncResult ar)
        {
            try
            {
                IPEndPoint ip = new IPEndPoint(IPAddress.Any, 0);
                byte[] data = Client.EndReceive(ar, ref ip);
                if (ReceiveDataEvent != null)
                {
                    ReceiveDataEvent(data, ip);
                }

                Common.Log(string.Format("IP:{0}", ip));
                Console.WriteLine(Common.BytesToHex(data));
                Console.WriteLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);

            }
            finally
            {
                StartReceive();
            }
        }

        public void Send(byte[] sData, string ipAddr)
        {
            Send(sData, new IPEndPoint(IPAddress.Parse(ipAddr), 80));
        }
        public void SendBrodCast(byte[] sData)
        {
            Send(sData, new IPEndPoint(IPAddress.Broadcast, 80));
        }


        public void Send(byte[] data, IPEndPoint ip)
        {
            Client.BeginSend(data, data.Length, ip, new AsyncCallback(OnSend), Client);
        }

        private void OnSend(IAsyncResult ar)
        {
            try
            {
                Client.EndSend(ar);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Client.BeginReceive(new AsyncCallback(OnReceive), Client);
            }
            
        }
    }

}
